
package com.dzirtbry.gui;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.io.*;

import javax.swing.*;
import javax.swing.filechooser.FileFilter;

@SuppressWarnings("serial")
public class TextEditorUI extends JFrame implements ItemListener, ActionListener{
	
	private enum OS {NIX, WIN};
	private static final int SAVE = 1;
	private static final int LOAD = 2;
	
	private JTextArea 		textArea;
	private JButton 		saveButton;
	private JButton 		loadButton;
	private JCheckBox 		wrapCheckBox;
	private File 			file;
	private OS				currentOs;
	
	public TextEditorUI() {
		super("Tiny text editor");
		init();
	}
	
	
	private void init(){
		try {
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		} catch (Exception e){
			e.printStackTrace();
		}
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		textArea = new JTextArea(15, 50);
		textArea.setLineWrap(true);
		textArea.setWrapStyleWord(true);
		JScrollPane scrollPane =  new JScrollPane(textArea);
		scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
		scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
		this.getContentPane().add(BorderLayout.CENTER,scrollPane);
		saveButton = new JButton("Save");
		loadButton = new JButton("Load");
		saveButton.addActionListener(this);
		loadButton.addActionListener(this);
		String os = System.getProperty("os.name").toLowerCase();
		if ((os.indexOf("nix") >=0 ) || (os.indexOf("nux") >=0 )) {
			currentOs = OS.NIX;
		} else {
			currentOs = OS.WIN;
		}
		if (os.indexOf("win") >=0 ) {
			textArea.setFont(new Font ("Arial",Font.PLAIN,16));
		}
		wrapCheckBox = new JCheckBox("Word wrap", true);
		wrapCheckBox.addItemListener(this);
		JPanel buttonPanel = new JPanel();
		buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.X_AXIS));
		buttonPanel.add(wrapCheckBox);
		buttonPanel.add(saveButton);
		buttonPanel.add(loadButton);
		this.getContentPane().add(BorderLayout.SOUTH, buttonPanel);
		this.pack();
		this.setVisible(true);
	}
	
	private void initWindowsSaveLoadWindow(int action) {
		FilenameFilter filenameFilter = new FilenameFilter() {
			
			@Override
			public boolean accept(File dir, String name) {
				return name.toLowerCase().endsWith(".txt");
			}
		};
		
		if (action == SAVE) {
				FileDialog fileDialog = new FileDialog(this, "Save file", FileDialog.SAVE);
				fileDialog.setFilenameFilter(filenameFilter);
				fileDialog.setVisible(true);
				if (fileDialog.getFile() != null){
					file = new File (fileDialog.getDirectory() + fileDialog.getFile());
					saveFile();
				}
			} else {
				FileDialog fileDialog = new FileDialog(this, "Open file", FileDialog.LOAD);
				fileDialog.setFilenameFilter(filenameFilter);
				fileDialog.setVisible(true);
				if (fileDialog.getFile() != null) {
					file = new File (fileDialog.getDirectory() + fileDialog.getFile());
					loadFile();
				}
			}
		}
	
	private void initUnixSaveLoadWindow (int action) {
		FileFilter fileFilter = new FileFilter() {
			
			@Override
			public boolean accept(File pathname) {
				return pathname.isDirectory() || pathname.getName().toLowerCase().endsWith(".txt");
			}

			@Override
			public String getDescription() {
				return "Text file (*.txt)";
			}
		};
		
		JFileChooser fileChooser = new JFileChooser();
		fileChooser.setFileFilter(fileFilter);
		if (action == SAVE) {
			if (fileChooser.showSaveDialog(this) == JFileChooser.APPROVE_OPTION) {
				file = fileChooser.getSelectedFile();
				saveFile();
			}
		} else {
			if (fileChooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
				file = fileChooser.getSelectedFile();
				loadFile();
			}
		}
	}
		
	public void saveFile() {
		if (file == null) return;
		if (!file.getName().toLowerCase().endsWith(".txt")) {
			String newFileName = file.getName() + ".txt";
			file = new File(file.getParent(), newFileName);
		}
		try {
			FileWriter writer = new FileWriter(file);
			writer.write(textArea.getText());
			writer.close();
		} catch (IOException e) {
			JOptionPane.showMessageDialog(this, "An error occurred while writing file", "Error", JOptionPane.ERROR_MESSAGE);
			e.printStackTrace();
		}
	}
	
	public void loadFile() {
		if (file == null) return;
		
		try {
			FileReader fileReader = new FileReader(file);
			BufferedReader reader = new BufferedReader(fileReader);
			String line;
			try {
				textArea.setText(null);
				while ((line = reader.readLine()) != null) {
					textArea.append(line + System.getProperty("line.separator"));
				}
			} catch (IOException e) {
				JOptionPane.showMessageDialog(this, "An error occurred while reading file", "Error", JOptionPane.ERROR_MESSAGE);
				e.printStackTrace();
			}
		} catch (FileNotFoundException e) {
			JOptionPane.showMessageDialog(this, "File not found", "Error", JOptionPane.ERROR_MESSAGE);
			e.printStackTrace();
		}
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		int action = e.getSource() == saveButton ? SAVE:LOAD;
		switch (currentOs) {
		case NIX:
			initUnixSaveLoadWindow(action);
			break;
		case WIN:
			initWindowsSaveLoadWindow(action);
			break;
		default:
			break;
		}
	}

	@Override
	public void itemStateChanged(ItemEvent e) {
		textArea.setLineWrap(wrapCheckBox.isSelected());
	}
	
	public static void main(String[] args) {
		new TextEditorUI();
	}
}
